<template>
  <div class="charts-container">
    <!-- 费用趋势折线图 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>费用趋势分析</h3>
          <el-select v-model="trendPeriod" placeholder="选择时间范围" size="small">
            <el-option label="最近7天" value="7"></el-option>
            <el-option label="最近30天" value="30"></el-option>
            <el-option label="最近90天" value="90"></el-option>
          </el-select>
        </div>
      </template>
      <v-chart class="chart" :option="trendChartOption" autoresize />
    </el-card>

    <!-- 比赛项目分布饼图 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>比赛项目分布</h3>
          <el-button type="primary" size="small" @click="refreshCompetitionData">
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </template>
      <v-chart class="chart" :option="competitionChartOption" autoresize />
    </el-card>

    <!-- 缴费状态统计柱状图 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>缴费状态统计</h3>
          <el-tag type="success">{{ totalEntries }} 总报名</el-tag>
        </div>
      </template>
      <v-chart class="chart" :option="statusChartOption" autoresize />
    </el-card>

    <!-- 月度收入雷达图 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>月度收入分析</h3>
          <el-tag type="warning">{{ currentYear }}年</el-tag>
        </div>
      </template>
      <v-chart class="chart" :option="radarChartOption" autoresize />
    </el-card>

    <!-- 实时数据仪表盘 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>实时数据仪表盘</h3>
          <el-switch v-model="autoRefresh" active-text="自动刷新" />
        </div>
      </template>
      <div class="gauge-container">
        <div class="gauge-item">
          <v-chart class="gauge-chart" :option="incomeGaugeOption" autoresize />
          <div class="gauge-label">总收入</div>
        </div>
        <div class="gauge-item">
          <v-chart class="gauge-chart" :option="entriesGaugeOption" autoresize />
          <div class="gauge-label">报名人数</div>
        </div>
        <div class="gauge-item">
          <v-chart class="gauge-chart" :option="completionGaugeOption" autoresize />
          <div class="gauge-label">完成率</div>
        </div>
      </div>
    </el-card>

    <!-- 热力图 -->
    <el-card class="chart-card" shadow="hover">
      <template #header>
        <div class="chart-header">
          <h3>报名热度热力图</h3>
          <el-select v-model="heatmapMetric" placeholder="选择指标" size="small">
            <el-option label="报名人数" value="entries"></el-option>
            <el-option label="收入金额" value="income"></el-option>
            <el-option label="完成率" value="completion"></el-option>
          </el-select>
        </div>
      </template>
      <v-chart class="chart" :option="heatmapOption" autoresize />
    </el-card>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, BarChart, PieChart, RadarChart, GaugeChart, HeatmapChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  VisualMapComponent
} from 'echarts/components'
import VChart from 'vue-echarts'
import { Refresh } from '@element-plus/icons-vue'

// 注册 ECharts 组件
use([
  CanvasRenderer,
  LineChart,
  BarChart,
  PieChart,
  RadarChart,
  GaugeChart,
  HeatmapChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  VisualMapComponent
])

// 响应式数据
const trendPeriod = ref('30')
const autoRefresh = ref(true)
const heatmapMetric = ref('entries')
const currentYear = new Date().getFullYear()

// 模拟数据
const generateTrendData = (days) => {
  const data = []
  const now = new Date()
  for (let i = days - 1; i >= 0; i--) {
    const date = new Date(now)
    date.setDate(date.getDate() - i)
    data.push({
      date: date.toISOString().slice(0, 10),
      income: Math.floor(Math.random() * 5000) + 1000,
      entries: Math.floor(Math.random() * 50) + 10
    })
  }
  return data
}

const generateCompetitionData = () => {
  return [
    { name: '篮球比赛', value: 45, color: '#5470c6' },
    { name: '足球比赛', value: 38, color: '#91cc75' },
    { name: '游泳比赛', value: 32, color: '#fac858' },
    { name: '田径比赛', value: 28, color: '#ee6666' },
    { name: '乒乓球', value: 25, color: '#73c0de' },
    { name: '羽毛球', value: 22, color: '#3ba272' }
  ]
}

const generateMonthlyData = () => {
  const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
  return months.map((month, index) => ({
    month,
    income: Math.floor(Math.random() * 50000) + 10000,
    entries: Math.floor(Math.random() * 500) + 100,
    completion: Math.floor(Math.random() * 30) + 70
  }))
}

// 计算属性
const trendData = computed(() => generateTrendData(parseInt(trendPeriod.value)))
const competitionData = ref(generateCompetitionData())
const monthlyData = ref(generateMonthlyData())

const totalEntries = computed(() => competitionData.value.reduce((sum, item) => sum + item.value, 0))
const totalIncome = computed(() => trendData.value.reduce((sum, item) => sum + item.income, 0))

// 图表配置
const trendChartOption = computed(() => ({
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross'
    }
  },
  legend: {
    data: ['收入金额', '报名人数']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: trendData.value.map(item => item.date),
    axisLabel: {
      rotate: 45
    }
  },
  yAxis: [
    {
      type: 'value',
      name: '收入金额 (元)',
      position: 'left'
    },
    {
      type: 'value',
      name: '报名人数',
      position: 'right'
    }
  ],
  series: [
    {
      name: '收入金额',
      type: 'line',
      smooth: true,
      data: trendData.value.map(item => item.income),
      itemStyle: {
        color: '#5470c6'
      },
      areaStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [
            { offset: 0, color: 'rgba(84, 112, 198, 0.3)' },
            { offset: 1, color: 'rgba(84, 112, 198, 0.1)' }
          ]
        }
      }
    },
    {
      name: '报名人数',
      type: 'line',
      smooth: true,
      yAxisIndex: 1,
      data: trendData.value.map(item => item.entries),
      itemStyle: {
        color: '#91cc75'
      }
    }
  ]
}))

const competitionChartOption = computed(() => ({
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c} ({d}%)'
  },
  legend: {
    orient: 'vertical',
    left: 'left',
    top: 'middle'
  },
  series: [
    {
      name: '比赛项目',
      type: 'pie',
      radius: ['40%', '70%'],
      center: ['60%', '50%'],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: '18',
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      data: competitionData.value
    }
  ]
}))

const statusChartOption = computed(() => ({
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: ['已缴费', '待缴费', '已取消', '已完成']
  },
  yAxis: {
    type: 'value',
    name: '人数'
  },
  series: [
    {
      name: '报名状态',
      type: 'bar',
      data: [
        { value: 120, itemStyle: { color: '#67c23a' } },
        { value: 45, itemStyle: { color: '#e6a23c' } },
        { value: 15, itemStyle: { color: '#f56c6c' } },
        { value: 80, itemStyle: { color: '#409eff' } }
      ],
      barWidth: '60%',
      itemStyle: {
        borderRadius: [4, 4, 0, 0]
      }
    }
  ]
}))

const radarChartOption = computed(() => ({
  tooltip: {
    trigger: 'item'
  },
  legend: {
    data: ['收入', '报名人数', '完成率']
  },
  radar: {
    indicator: monthlyData.value.map(item => ({ name: item.month, max: 100 })),
    radius: '65%'
  },
  series: [
    {
      name: '月度数据',
      type: 'radar',
      data: [
        {
          value: monthlyData.value.map(item => (item.income / 50000) * 100),
          name: '收入',
          itemStyle: { color: '#5470c6' }
        },
        {
          value: monthlyData.value.map(item => (item.entries / 500) * 100),
          name: '报名人数',
          itemStyle: { color: '#91cc75' }
        },
        {
          value: monthlyData.value.map(item => item.completion),
          name: '完成率',
          itemStyle: { color: '#fac858' }
        }
      ]
    }
  ]
}))

const incomeGaugeOption = computed(() => ({
  series: [
    {
      type: 'gauge',
      startAngle: 180,
      endAngle: 0,
      min: 0,
      max: 100000,
      splitNumber: 8,
      axisLine: {
        lineStyle: {
          width: 6,
          color: [
            [0.25, '#ff6e76'],
            [0.5, '#fddd60'],
            [0.75, '#58d9f9'],
            [1, '#7cffb2']
          ]
        }
      },
      pointer: {
        icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
        length: '12%',
        width: 20,
        offsetCenter: [0, '-60%'],
        itemStyle: {
          color: 'auto'
        }
      },
      axisTick: {
        length: 12,
        lineStyle: {
          color: 'auto',
          width: 2
        }
      },
      splitLine: {
        length: 20,
        lineStyle: {
          color: 'auto',
          width: 5
        }
      },
      axisLabel: {
        color: '#464646',
        fontSize: 20,
        distance: -60,
        formatter: function (value) {
          return value + '元'
        }
      },
      title: {
        offsetCenter: [0, '-20%'],
        fontSize: 20
      },
      detail: {
        fontSize: 30,
        offsetCenter: [0, '0%'],
        valueAnimation: true,
        formatter: function (value) {
          return Math.round(value) + '元'
        },
        color: 'auto'
      },
      data: [
        {
          value: totalIncome.value
        }
      ]
    }
  ]
}))

const entriesGaugeOption = computed(() => ({
  series: [
    {
      type: 'gauge',
      startAngle: 180,
      endAngle: 0,
      min: 0,
      max: 300,
      splitNumber: 8,
      axisLine: {
        lineStyle: {
          width: 6,
          color: [
            [0.25, '#ff6e76'],
            [0.5, '#fddd60'],
            [0.75, '#58d9f9'],
            [1, '#7cffb2']
          ]
        }
      },
      pointer: {
        icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
        length: '12%',
        width: 20,
        offsetCenter: [0, '-60%'],
        itemStyle: {
          color: 'auto'
        }
      },
      axisTick: {
        length: 12,
        lineStyle: {
          color: 'auto',
          width: 2
        }
      },
      splitLine: {
        length: 20,
        lineStyle: {
          color: 'auto',
          width: 5
        }
      },
      axisLabel: {
        color: '#464646',
        fontSize: 20,
        distance: -60,
        formatter: function (value) {
          return value + '人'
        }
      },
      title: {
        offsetCenter: [0, '-20%'],
        fontSize: 20
      },
      detail: {
        fontSize: 30,
        offsetCenter: [0, '0%'],
        valueAnimation: true,
        formatter: function (value) {
          return Math.round(value) + '人'
        },
        color: 'auto'
      },
      data: [
        {
          value: totalEntries.value
        }
      ]
    }
  ]
}))

const completionGaugeOption = computed(() => ({
  series: [
    {
      type: 'gauge',
      startAngle: 180,
      endAngle: 0,
      min: 0,
      max: 100,
      splitNumber: 8,
      axisLine: {
        lineStyle: {
          width: 6,
          color: [
            [0.25, '#ff6e76'],
            [0.5, '#fddd60'],
            [0.75, '#58d9f9'],
            [1, '#7cffb2']
          ]
        }
      },
      pointer: {
        icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
        length: '12%',
        width: 20,
        offsetCenter: [0, '-60%'],
        itemStyle: {
          color: 'auto'
        }
      },
      axisTick: {
        length: 12,
        lineStyle: {
          color: 'auto',
          width: 2
        }
      },
      splitLine: {
        length: 20,
        lineStyle: {
          color: 'auto',
          width: 5
        }
      },
      axisLabel: {
        color: '#464646',
        fontSize: 20,
        distance: -60,
        formatter: function (value) {
          return value + '%'
        }
      },
      title: {
        offsetCenter: [0, '-20%'],
        fontSize: 20
      },
      detail: {
        fontSize: 30,
        offsetCenter: [0, '0%'],
        valueAnimation: true,
        formatter: function (value) {
          return Math.round(value) + '%'
        },
        color: 'auto'
      },
      data: [
        {
          value: 85
        }
      ]
    }
  ]
}))

const heatmapOption = computed(() => {
  const hours = ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
  const days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
  
  const data = []
  for (let i = 0; i < 7; i++) {
    for (let j = 0; j < 12; j++) {
      data.push([j, i, Math.floor(Math.random() * 100)])
    }
  }

  return {
    tooltip: {
      position: 'top'
    },
    grid: {
      height: '50%',
      top: '10%'
    },
    xAxis: {
      type: 'category',
      data: hours,
      splitArea: {
        show: true
      }
    },
    yAxis: {
      type: 'category',
      data: days,
      splitArea: {
        show: true
      }
    },
    visualMap: {
      min: 0,
      max: 100,
      calculable: true,
      orient: 'horizontal',
      left: 'center',
      bottom: '15%'
    },
    series: [{
      name: '报名热度',
      type: 'heatmap',
      data: data,
      label: {
        show: true
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }]
  }
})

// 方法
const refreshCompetitionData = () => {
  competitionData.value = generateCompetitionData()
}

let refreshTimer = null

// 监听器
watch(autoRefresh, (newVal) => {
  if (newVal) {
    refreshTimer = setInterval(() => {
      // 模拟数据更新
      competitionData.value = generateCompetitionData()
      monthlyData.value = generateMonthlyData()
    }, 5000)
  } else {
    if (refreshTimer) {
      clearInterval(refreshTimer)
      refreshTimer = null
    }
  }
})

// 生命周期
onMounted(() => {
  if (autoRefresh.value) {
    refreshTimer = setInterval(() => {
      competitionData.value = generateCompetitionData()
      monthlyData.value = generateMonthlyData()
    }, 5000)
  }
})

onUnmounted(() => {
  if (refreshTimer) {
    clearInterval(refreshTimer)
  }
})
</script>

<style scoped>
.charts-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
  gap: var(--spacing-lg);
  padding: var(--spacing-lg);
}

.chart-card {
  border-radius: var(--radius-lg);
  transition: all 0.3s ease;
}

.chart-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chart-header h3 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1.1rem;
  font-weight: 600;
}

.chart {
  height: 300px;
  width: 100%;
}

.gauge-container {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 200px;
}

.gauge-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.gauge-chart {
  height: 150px;
  width: 150px;
}

.gauge-label {
  margin-top: var(--spacing-sm);
  font-size: 0.9rem;
  color: var(--text-secondary);
  font-weight: 500;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .charts-container {
    grid-template-columns: 1fr;
    gap: var(--spacing-md);
    padding: var(--spacing-md);
  }

  .chart {
    height: 250px;
  }

  .gauge-container {
    flex-direction: column;
    gap: var(--spacing-lg);
    height: auto;
  }

  .gauge-chart {
    height: 120px;
    width: 120px;
  }
}

@media (max-width: 480px) {
  .chart-header {
    flex-direction: column;
    gap: var(--spacing-sm);
    align-items: flex-start;
  }

  .chart {
    height: 200px;
  }
}
</style>
